package com.yonyou.cyxdms.sysAuth.service.controller;

        import com.baomidou.mybatisplus.core.metadata.IPage;
        import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
        import com.xiaoleilu.hutool.bean.BeanUtil;
        import com.yonyou.cyx.framework.compent.redis.RedisClient;
        import com.yonyou.cyx.framework.controller.base.BaseController;
        import com.yonyou.cyx.framework.util.bean.ApplicationContextHelper;
        import com.yonyou.cyx.function.exception.ServiceBizException;
        import com.yonyou.cyx.function.utils.jsonserializer.JSONUtil;
        import com.yonyou.cyxdms.framework.bean.dto.user_info.LoginInfoDto;
        import com.yonyou.cyxdms.framework.constants.FrameworkDictCodeConstants;
        import com.yonyou.cyxdms.sysAuth.service.config.Redis;
        import com.yonyou.cyxdms.sysAuth.service.constants.SysAuthDictCodeConstants;
        import com.yonyou.cyxdms.sysAuth.service.constants.UserAuthConstant;
        import com.yonyou.cyxdms.sysAuth.service.dto.authorization.ImLoginInfoDto;
        import com.yonyou.cyxdms.sysAuth.service.dto.authorization.LoginInfo;
        import com.yonyou.cyxdms.sysAuth.service.dto.user.SyncUserDTO;
        import com.yonyou.cyxdms.sysAuth.service.dto.user.UpdatePasswordDTO;
        import com.yonyou.cyxdms.sysAuth.service.dto.user.UpdateUserInfoDTO;
        import com.yonyou.cyxdms.sysAuth.service.dto.user.UserDTO;
        import com.yonyou.cyxdms.sysAuth.service.service.SystemParamService;
        import com.yonyou.cyxdms.sysAuth.service.service.UserAuthService;
        import com.yonyou.cyxdms.sysAuth.service.service.UserService;
        import com.yonyou.cyxdms.sysAuth.service.vo.user.UserRoleVO;
        import io.swagger.annotations.Api;
        import io.swagger.annotations.ApiImplicitParam;
        import io.swagger.annotations.ApiImplicitParams;
        import io.swagger.annotations.ApiOperation;
        import org.apache.commons.lang.StringUtils;
        import org.slf4j.Logger;
        import org.slf4j.LoggerFactory;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.http.HttpStatus;
        import org.springframework.web.bind.annotation.*;

        import java.util.List;
        import java.util.Map;
        import java.util.concurrent.TimeUnit;


/**
 * @author zhangxianchao
 * @since 2018-09-13
 */
@RestController
@Api(value = "用户相关", tags = {"用户相关"})
@RequestMapping("/user")
public class UserController extends BaseController {
    private final Logger logger = LoggerFactory.getLogger(UserController.class);

    private static final String user_key_pc = "cyxdms:sysAuth:user:10041001";
    private static final String user_key_app = "cyxdms:sysAuth:user:10041002";
    private static final String AUTH_USERINFO_KEY = "sysmanage:userInfo:";

    @Autowired
    UserService userService;

    @Autowired
    RedisClient redisClient;

    @Autowired
    Redis redis;

    @Autowired
    SystemParamService systemParamService;

    /**
     * 分页查询数据
     *
     * @param queryCondition 查询条件
     * @return com.baomidou.mybatisplus.core.metadata.IPage 分页对象
     * @author zhangxianchao
     * @since 2018-09-13
     */
    @ResponseBody
    @GetMapping
    @SuppressWarnings("unchecked")
    public IPage<Map<String, Object>> getList(@RequestParam Map<String, Object> queryCondition, @RequestParam
            ("currentPage") int currentPage, @RequestParam("pageSize") int pageSize) {
        Page<Map<String, Object>> page = new Page(currentPage, pageSize);
        return userService.selectPageBysql(page, queryCondition);
    }

    /**
     * 进行数据修改
     *
     * @param id 数据主键ID
     * @return Map<String, Object> 数据对应的map 结构
     * @author zhangxianchao
     * @since 2018-09-13
     */
    @ResponseBody
    @GetMapping(value = "/{id}")
    @SuppressWarnings("unchecked")
    public Map<String, Object> getById(@PathVariable("id") Long id) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        logger.debug("LoginInfoDto:{}", loginInfoDto);
        return userService.getById(id);
    }

    /**
     * 进行数据新增
     *
     * @param userDTO 需要保存的DTO
     * @return Map<String, Object> 返回的数据map
     * @author zhangxianchao
     * @since 2018-09-13
     */
    @ResponseBody
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    @SuppressWarnings("unchecked")
    public Map<String, Object> insert(@RequestBody UserDTO userDTO) {
        logger.debug("userDTO:{}", userDTO);
        return userService.insert(userDTO);
    }

    /**
     * 进行数据修改
     *
     * @param id      需要修改数据的ID
     * @param userDTO 需要保存的DTO
     * @return Map<String, Object> 返回的数据map
     * @author zhangxianchao
     * @since 2018-09-13
     */
    @ResponseBody
    @PutMapping(value = "/{id}")
    @ResponseStatus(HttpStatus.CREATED)
    @SuppressWarnings("unchecked")
    public Map<String, Object> update(@PathVariable("id") Long id, @RequestBody UserDTO userDTO) {
        logger.debug("userDTO:{}", userDTO);
        return userService.update(id, userDTO);
    }

    /**
     * 根据jwt 获取用户信息
     *
     * @param paramMap paramMap 对象
     * @param headMap  headMap 对象
     * @return Map<String, Object> 数据对应的map 结构
     * @author zhangxianchao
     * @since 2018-09-13
     */
    @ResponseBody
    @GetMapping(value = "/userInfo/token")
    @SuppressWarnings("unchecked")
    public LoginInfoDto getUserInfoByUserCode(@RequestParam Map<String, String> paramMap,
                                              @RequestHeader Map<String, String> headMap) {
        logger.debug("认证开始---------------------\nparamMap:{}\nheadMap:{}",
                JSONUtil.objectToJson(paramMap), JSONUtil.objectToJson(headMap));

        String userAgent = headMap.get(UserAuthConstant.USER_AGENT);
        String appId = getAppId(paramMap, headMap);
        String jwt = getJwt(paramMap, headMap);

        logger.debug("token:{},appId:{},userAgent{}", jwt, appId, userAgent);
        //根据广汽三菱的实现获取用户信息
        UserAuthService userAuthService = ApplicationContextHelper.getBeanByName(UserAuthConstant
                .SERVICE_NAME_USER_AUTH + appId, UserAuthService.class);

        if (userAuthService == null) {
            // 默认实现
            return userService.getAppUserInfo(appId, jwt, userAgent);
        }

        return userAuthService.getAppUserInfo(jwt);
    }

    private String getJwt(Map<String, String> paramMap, Map<String, String> headMap) {
        String jwt = headMap.get(UserAuthConstant.TOKEN_NAME);
        if (jwt == null) {
            jwt = paramMap.get(UserAuthConstant.TOKEN_NAME);
        }
        return jwt;
    }

    private String getAppId(Map<String, String> paramMap, Map<String, String> headMap) {
        String appId = headMap.get(UserAuthConstant.APP_SOURCE_CODE);
        if (appId == null) {
            appId = paramMap.get(UserAuthConstant.APP_SOURCE_CODE);
            if (appId == null) {
                appId = headMap.get(UserAuthConstant.APP_SOURCE_LOWER_CODE);
                if (appId == null) {
                    appId = paramMap.get(UserAuthConstant.APP_SOURCE_LOWER_CODE);
                }
            }
        }
        return appId;
    }


    /**
     * 通用获取userId
     *
     * @param userCode
     * @return java.lang.Long
     * @author zhangsx
     * @since 2018/11/8
     */
    @ResponseBody
    @GetMapping(value = "/userId/params")
    public Long getUserInfoByParams(@RequestParam("userCode") String userCode, @RequestParam("appId") String appId) {
        return userService.getUserInfoByParams(userCode, appId);
    }

    @ResponseBody
    @PostMapping(value = "/syncUser")
    public Long syncUser(@RequestBody SyncUserDTO syncUserDTO) {
        logger.debug("客服系统用户信息同步：{}", JSONUtil.objectToJson(syncUserDTO));
        return userService.syncUser(syncUserDTO);
    }

    /**
     * 更新用户信息
     *
     * @param updateUserInfoDTO
     * @return
     */
    @ResponseBody
    @PostMapping(value = "/updateUserInfo")
    public Boolean updateUserInfo(@RequestBody UpdateUserInfoDTO updateUserInfoDTO) {
        return userService.updateUserInfo(updateUserInfoDTO);
    }

    /**
     * 更新用戶密码
     *
     * @param updatePasswordDTO
     * @return
     */
    @ResponseBody
    @PostMapping(value = "/updatePassword")
    public Boolean updatePassword(@RequestBody UpdatePasswordDTO updatePasswordDTO) {
        return userService.updatePassword(updatePasswordDTO);
    }

    /**
     * 根据用户ID查询dealerId
     *
     * @param userId
     * @return
     */
    @ResponseBody
    @GetMapping(value = "/getDealerId")
    public Long getDealerId(@RequestParam("userId") Long userId) {
        return userService.getDealerId(userId);
    }


    @GetMapping("/getUserInfo")
    public ImLoginInfoDto getUserInfo(@RequestParam(value = "appId", required = true) String appId,
                                      @RequestHeader(value = "jwt", required = true) String jwt,
                                      @RequestHeader(value = "userAgent", required = false) String userAgent) {
        logger.debug("jwt:{},appId:{}", jwt, appId);
        // 根据广汽三菱的实现获取用户信息
        UserAuthService userAuthService = ApplicationContextHelper
                .getBeanByName(UserAuthConstant.SERVICE_NAME_USER_AUTH + appId, UserAuthService.class);

        LoginInfoDto loginInfoDto;

        if (userAuthService == null) {
            // 默认实现
            int agent = (StringUtils.isBlank(userAgent) || "pc".equals(userAgent) || userAgent.equals(String.valueOf(SysAuthDictCodeConstants.STATUS_IS_YES)))
                    ? SysAuthDictCodeConstants.STATUS_IS_YES : SysAuthDictCodeConstants.STATUS_IS_NOT;
            loginInfoDto = userService.getAppUserInfo(appId, jwt, String.valueOf(agent));
        } else {
            loginInfoDto = userAuthService.getAppUserInfo(jwt);
        }

        ImLoginInfoDto imLoginInfoDto = new ImLoginInfoDto();
        BeanUtil.copyProperties(loginInfoDto, imLoginInfoDto);

        imLoginInfoDto.setConsultantId(String.valueOf(loginInfoDto.getUserId()));
        imLoginInfoDto.setUserAccount(loginInfoDto.getUserCode());
        // 补充经销商信息
        imLoginInfoDto.setDealerCode(loginInfoDto.getOwnerCode());
        imLoginInfoDto.setDealerId(StringUtils.isEmpty(loginInfoDto.getOwnerId()) ? null : Long.valueOf(loginInfoDto.getOwnerId()));
        imLoginInfoDto.setLoginWay(StringUtils.isNotEmpty(loginInfoDto.getLoginWay()) && StringUtils.equals(loginInfoDto.getLoginWay().toLowerCase(), "pc") ? 10051001 : 10051002);
        imLoginInfoDto.setUuid(loginInfoDto.getUuid());

        if (!StringUtils.isEmpty(userAgent)) {
            setValue(userAgent, loginInfoDto, imLoginInfoDto);
        } else if (!StringUtils.isBlank(loginInfoDto.getLoginWay())) {
            userAgent = (String.valueOf(FrameworkDictCodeConstants.LOGIN_WAY_PC).equals(loginInfoDto.getLoginWay())) ? "pc" : "app";
            setValue(userAgent, loginInfoDto, imLoginInfoDto);
        }

        return imLoginInfoDto;
    }

    private void setValue(String userAgent, LoginInfoDto loginInfoDto, ImLoginInfoDto imLoginInfoDto) {
        if (!StringUtils.isBlank(userAgent)) {
            Object o = redisClient.hashOperations.get(userAgent.toLowerCase().contains("pc")
                    ? user_key_pc : user_key_app, String.valueOf(loginInfoDto.getUserId()));
            if (o != null) {
                LoginInfo info = JSONUtil.jsonToObj(JSONUtil.objectToJson(o), LoginInfo.class);

                if (imLoginInfoDto.getUserAccount() == null) {
                    imLoginInfoDto.setUserAccount(info.getUserCode());
                }
                if (imLoginInfoDto.getDealerId() == null) {
                    imLoginInfoDto.setDealerId(Long.parseLong(info.getOwnerId()));
                }
                if (imLoginInfoDto.getDealerCode() == null) {
                    imLoginInfoDto.setDealerCode(info.getOwnerCode());
                }
                if (imLoginInfoDto.getUserId() == null) {
                    imLoginInfoDto.setUserId(info.getUserId());
                }
            }
        }
    }

    /**
     * 根据userId和userOrgId返回角色类别
     *
     * @date 2019-10-28  adu
     */
    @ApiOperation(value = "查询-角色类别")
    @GetMapping(value = "/userId/getRoleType")
    public Map<String, Object> getRoleTypeParams(@RequestParam(value = "userId", required = false) Integer userId, @RequestParam(value = "userOrgId", required = false) Integer userOrgId) {
        if (null == userId && null == userOrgId) {
            return null;
        }
        //传userOrgId其实是orgid
        return userService.getRoleTypeParams(userId, userOrgId);
    }

    @ApiOperation(value = "用户数量")
    @GetMapping(value = "/userCount")
    @ApiImplicitParams({@ApiImplicitParam(value = "用户id", name = "userId", required = true, dataType = "string", paramType = "header")})
    public Long getUserCount() {
        return userService.getUserCount();
    }

    /**
     * PostersTemplateController
     * 根据jwt去外系统认证
     *
     * @param paramMap paramMap 对象
     * @param headMap  headMap 对象
     * @return Map<String, Object> 数据对应的map 结构
     * @author zhangxianchao
     * @since 2018-09-13
     */
    @GetMapping("/auth")
    public LoginInfoDto subSystemAuth(@RequestParam Map<String, String> paramMap,
                                      @RequestHeader Map<String, String> headMap) {
        logger.debug("子系统认证开始");
        String appId = getAppId(paramMap, headMap);
        String jwt = getJwt(paramMap, headMap);

        logger.debug("token:{},appId:{}", jwt, appId);
        return getLoginInfoDto(appId, jwt);
    }

    private LoginInfoDto getLoginInfoDto(String appId, String jwt) {
        // 根据广汽三菱的实现获取用户信息
        UserAuthService userAuthService = ApplicationContextHelper
                .getBeanByName(UserAuthConstant.SERVICE_NAME_USER_AUTH + appId, UserAuthService.class);
        String key = AUTH_USERINFO_KEY + appId + ":" + jwt;
        LoginInfoDto infoDto = redis.GET(key, LoginInfoDto.class);
        if (infoDto != null) {
            return infoDto;
        } else {
            String url = systemParamService.getParamValueByCode(UserAuthConstant.AUTH, appId);
            if (com.yonyou.cyx.function.utils.common.StringUtils.isBlank(url)) {
                throw new ServiceBizException("未实现的认证配置，appId:{}", appId);
            }
            // 根据具体的实现获取用户信息
            LoginInfoDto dto = userAuthService.getAppUserInfo(appId, jwt, url);
            redis.SETEX(key, dto, 1, TimeUnit.HOURS);
            return dto;
        }
    }

    @GetMapping("/getUserIdByUserCode")
    public UserDTO getUserIdByUserCode(@RequestParam("userCode") String userCode,
                                       @RequestParam("appId") String appId) {
        return this.userService.getUserIdByUserCode(userCode, appId);
    }


    /**
     * 长春CMS
     * 根据companyId 与appId 查询经销商角色信息
     */
    @ResponseBody
    @GetMapping(value = "/getRoleInfoByCompanyId")
    public List<UserRoleVO> getRoleInfoByCompanyId(@RequestParam("companyId") String companyId, @RequestParam("appId") String appId) {
        return userService.getRoleInfoByCompanyId(companyId, appId);
    }

    /**
     * 长春CMS
     * 根据menuId获取应有权限的OrgID集合
     */
    @ResponseBody
    @GetMapping(value = "/getUserIdByMenuId")
    public List<String> getUserIdByMenuId(@RequestParam("menuId") String menuId, @RequestParam("appId") String appId, @RequestParam("userId") String userId, @RequestParam("userCode") String userCode) {
        return userService.getUserIdByMenuId(menuId, appId, userId, userCode);
    }


    /**
     * 长春CMS
     * 向arcfoxAPP同步顾问信息
     */
    @GetMapping(value = "/sendConsultant")
    public void sendConsultant() {
         userService.sendConsultant();
    }

    /**
     * 检查是否离职
     */
    @GetMapping(value = "/checkEmployeeStatus")
    public Integer checkEmployeeStatus(@RequestParam("appId") String appId, @RequestParam("userId") Long userId) {
        return userService.checkEmployeeStatus(appId,userId);
    }

}
